package org.example.controller;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Pattern;
import org.example.pojo.User;
import org.example.service.UserService;
import org.example.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/user")
@Validated
public class UserController {

    @Autowired
    private JavaMailSender sender;

    @Autowired
    private UserService userService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    //注冊接口
    @PostMapping("/singin")
    public Result SignIn(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$") String password,
                         @Email String email, @Pattern(regexp = "^\\S{6}$") String verificationCode,
                         @NotEmpty String nickname) {
        //查询名称有无重复
        User u = userService.findByUsername(username);

        if (u == null) {
            //创建redis方法
            ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
            //没有重复名称
            //redis中是否存在验证码
            if (operations.get(email) == null) {
                //redis中没有对应验证码
                return Result.error("请获取验证码或验证码已过期");
            } else {
                //验证码存在
                //校验验证码
                if (operations.get(email).equals(verificationCode)) {
                    //验证码正确
                    //创建账号
                    userService.SignIn(username, password, email, nickname);
                    return Result.success("账号创建成功");
                } else {
                    //验证码错误
                    return Result.error("验证码错误");
                }
            }
        } else {
            //名称重复
            return Result.error("用户名已被占用");
        }
    }

    //注册验证码邮件接口
    @PostMapping("/email")
    public Result email(@RequestParam @Email @NotEmpty String email) {
        //生成随机数
        String randomNumber = generateRandomNumber();

        String content = "您的验证码为：" + randomNumber + "有效期为10分钟";

        //调用sendmail方法发送邮件
        sendmail(email, content);

        //将验证码存入redis中
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        operations.set(email, randomNumber, 10, TimeUnit.MINUTES);

        return Result.success("验证码发送成功");
    }

    //登录接口
    @PostMapping("/login")
    public Result Login(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$") String password) {
        //查询名称是否存在
        User byUsername = userService.findByUsername(username);

        if (byUsername == null) {
            //用户名不存在
            return Result.error("用户名不存在");
        } else {
            //用户名存在
            //判断密码是否正确
            if (Md5Util.getMD5String(password).equals(byUsername.getPassword())) {

                //密码正确
                //生成token令牌
                Map<String, Object> claims = new HashMap<>();
                claims.put("id", byUsername.getId());
                claims.put("username", byUsername.getUsername());
                String token = JwtUtil.genToken(claims);

                //将生成的token令牌存存储一份到Redis中，设置有效期，访问接口做二次令牌校验
                ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
                operations.set(token, token, 7, TimeUnit.DAYS);

                //登录成功，返回token
                return Result.success(token);
            } else {

                //密码错误
                return Result.error("密码错误");
            }
        }
    }

    //用户头像的添加
    @PostMapping("/upload")
    public Result<String> upload(MultipartFile file) throws Exception {
        //把文件上传到本地磁盘
        String originalFilename = file.getOriginalFilename();
        //保证文件名唯一，防止文件覆盖
        String filename = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));
//        file.transferTo(new File("C:\\Users\\LENOVO\\Desktop\\aaa\\" + filename));
        //添加阿里云oss存储
        String url = AilOssUtil.uploadFile(filename, file.getInputStream());
        userService.upload(url);
        return Result.success(url);
    }

    //名称的添加
    @PostMapping("/nickname")
    public Result nickname(String nickname) {
        userService.addCoupleName(nickname);
        return Result.success();
    }

    //用户信息详情查询
    @GetMapping("/findByUser")
    public Result<User> findByUser() {
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer id = (Integer) map.get("id");

        User user = userService.findByUser(id);

        return Result.success(user);
    }

    //通过旧密码修改密码
    @PatchMapping("/updatePwd")
    public Result updatePwd(@RequestBody Map<String, String> params, @RequestHeader("Authorization") String token) {
        //1.校验参数
        String oldPwd = params.get("old_pwd");
        String newPwd = params.get("new_pwd");
        String rePwd = params.get("re_pwd");

        if (!StringUtils.hasLength(oldPwd) || !StringUtils.hasLength(newPwd) || !StringUtils.hasLength(rePwd)) {
            return Result.error("缺少必要参数");
        }

        //原密码是否正确
        //调用UserService根据用户名拿到原密码，再拿到old_pwd对比
        Map<String, Object> map = ThreadLocalUtil.get();
        String username = (String) map.get("username");
        User loginUser = userService.findByUsername(username);
        if (!loginUser.getPassword().equals(Md5Util.getMD5String(oldPwd))) {
            return Result.error("原密码填写不正确");
        }

        //newPwd和rePwd是否一样
        if (!newPwd.equals(rePwd)) {
            return Result.error("密码填写与确认密码不一致");
        }
        //2.调用service完成密码更新
        userService.updatePwd(newPwd);

        //密码更新成功后删除redis中的token
        stringRedisTemplate.delete(token);

        return Result.success();
    }

    //验证码修改密码
    @PostMapping("/updatePwdEmail")
    public Result updatePwdEmail(String password, @Email String email, String verificationCode) {
        String a = userService.findByEamil(email);

        if (a == null) {
            return Result.error("邮箱错误，请检查后重试");
        } else {
            ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
            //从redis中获取邮箱验证码，与用户上传验证码是否一致
            if (operations.get(email).equals(verificationCode)) {
                //修改密码
                userService.updatePwdEmail(email, password);

                return Result.success("密码修改成功");
            } else {
                return Result.error("验证码错误");
            }

        }
    }


    //验证码随机数生成
    private String generateRandomNumber() {
        // 生成随机6位验证码
        Random random = new Random();
        int code = random.nextInt(900000) + 100000;
        return String.valueOf(code);
    }

    //邮件收发
    private void sendmail(String email, String content) {
        SimpleMailMessage mail = new SimpleMailMessage();

        try {
            //邮件标题
            mail.setSubject("验证码");
            //邮件内容
            mail.setText(content);
            mail.setTo(email);
            //邮件发送账户
            mail.setFrom("3182728716@qq.com");

            sender.send(mail);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }
}
